package com.wondertek.service.service.sys.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wondertek.common.config.UploadConfig;
import com.wondertek.service.dto.sys.req.SysUploadByUrlReq;
import com.wondertek.service.entity.sys.SysFilePo;
import com.wondertek.service.mapper.sys.SysFileMapper;
import com.wondertek.service.service.sys.ISysFileService;
import jakarta.annotation.Resource;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.net.URI;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author xqs
 */
@Slf4j
@Service
public class SysFileServiceImpl extends ServiceImpl<SysFileMapper, SysFilePo>
    implements ISysFileService {

    @Resource
    private UploadConfig uploadConfig;

    @SneakyThrows
    @Override
    public SysFilePo upload(MultipartFile file) {
        //文件对象
        SysFilePo sysFilePo = new SysFilePo();
        sysFilePo.setStartTime(new Date());
        //上传参数设置
        String extName = FileUtil.extName(file.getOriginalFilename());
        String fileName = IdUtil.fastSimpleUUID() + "." + extName;
        String fileDir = uploadConfig.getDirectory() + "/" + new DateTime().toDateStr() ;
        File fileIn = new File(fileDir);
        if (!fileIn.exists()) {
            boolean mkdirs = fileIn.mkdirs();
        }
        String filePath = fileDir + "/" + fileName;
        // 保存文件到磁盘
        file.transferTo(Path.of(filePath));
        // 保存文件对象
        sysFilePo.setOriginalFilename(file.getOriginalFilename());
        sysFilePo.setFileName(fileName);
        sysFilePo.setExtName(extName);
        sysFilePo.setFilePath(filePath);
        sysFilePo.setFileSize(FileUtil.readableFileSize(new File(filePath)));
        sysFilePo.setEndTime(new DateTime());
        this.save(sysFilePo);
        return getViewFile(sysFilePo);
    }

    private SysFilePo getViewFile(SysFilePo sysFilePo) {
        sysFilePo.setViewUrl(uploadConfig.getViewPrefix()+"/"+sysFilePo.getFileName());
        sysFilePo.setDownloadUrl(uploadConfig.getDownloadPrefix()+"/"+sysFilePo.getFileName());
        return sysFilePo;
    }

    public String getViewFile(String fileName) {
        if(StrUtil.isNotBlank(fileName)){
            return uploadConfig.getViewPrefix()+"/"+fileName;
        }
        return null;
    }

    @Override
    public List<SysFilePo> uploadBatch(MultipartFile[] files) {
        return Arrays.stream(files).map(this::upload).collect(Collectors.toList());
    }

    @Override
    @SneakyThrows
    public SysFilePo uploadByUrl(SysUploadByUrlReq sysUploadByUrlReq) {
        //文件对象
        SysFilePo sysFilePo = new SysFilePo();
        sysFilePo.setStartTime(new Date());
        //上传参数设置
        String originalFilename = Paths.get(new URI(sysUploadByUrlReq.getUrl()).getPath()).getFileName().toString();
        String extName = FileUtil.extName(originalFilename);
        String fileName = IdUtil.fastSimpleUUID() + "." + extName;
        String fileDir = uploadConfig.getDirectory() + "/" + new DateTime().toDateStr() ;
        File fileIn = new File(fileDir);
        if (!fileIn.exists()) {
            boolean mkdirs = fileIn.mkdirs();
        }
        String filePath = fileDir + "/" + fileName;
        File file =  new File(filePath);
        boolean newFile = file.createNewFile();
        // 保存文件到磁盘
        HttpUtil.downloadFileFromUrl(sysUploadByUrlReq.getUrl(),file);
        // 保存文件对象
        sysFilePo.setOriginalFilename(originalFilename);
        sysFilePo.setFileName(fileName);
        sysFilePo.setExtName(extName);
        sysFilePo.setFilePath(filePath);
        sysFilePo.setFileSize(FileUtil.readableFileSize(new File(filePath)));
        sysFilePo.setEndTime(new DateTime());
        this.save(sysFilePo);
        return getViewFile(sysFilePo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateBiz(String id, String bizType, String bizId) {
        SysFilePo sysFilePo = this.getById(id);
        sysFilePo.setBizType(bizType);
        sysFilePo.setBizId(bizId);
        this.updateById(sysFilePo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateBiz(List<String> id, String bizType, String bizId) {
        id.forEach(v->updateBiz(v,bizType, bizId));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<SysFilePo> findListByBiz(String bizType, String bizId) {
        return this.lambdaQuery()
                .eq(SysFilePo::getBizType,bizType)
                .eq(SysFilePo::getBizId,bizId)
                .list();
    }

    @Override
    public void deleteFile(String bizType, String bizId) {
        LambdaQueryWrapper<SysFilePo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysFilePo::getBizType,bizType).eq(SysFilePo::getBizId,bizId);
        this.remove(queryWrapper);
    }

}
